﻿using System.Threading;
using System.Threading.Tasks;

namespace CGF
{
    public class Heartbeat : ComponentBase, IAwake<TCPClient, int, int, object>, IDestroy
    {
        private TCPClient tcp;
        private bool isRuning;
        private const int SendSuccessInterval = 10; //成功则10秒后再发
        private const int SendFailInterval = 3; //失败则3秒后再发
        private int timer;
        private int sProtoId;
        public bool canSend;

        /// <param name="cProtoId">发送协议号</param>
        /// <param name="sProtoId">接收协议号</param>
        /// <param name="msgPack">发送cs消息包</param>
        public void Awake(TCPClient tcp, int cProtoId, int sProtoId, object msgPack)
        {
            this.tcp = tcp;
            this.tcp.onSubThreadReceiveMsg += OnSubThreadReceiveMsg;
            this.sProtoId = sProtoId;

            Task.Run(() =>
            {
                timer = SendSuccessInterval;
                isRuning = true;
                while (isRuning)
                {
                    Thread.Sleep(1000);
                    timer--;
                    if (timer < 0)
                    {
                        timer = SendFailInterval;
                        if (tcp.IsConnected && canSend)
                        {
                            //Log($"[{tcp.tag}] 客户端发送心跳 id:{cProtoId} cs[{msgPack.GetType().Name}]:{msgPack.ToJson()}");
                            tcp.Send(cProtoId, msgPack);
                        }
                    }
                }
            });
        }

        /// <summary>
        /// 本组件会第一时间插到TCPClient组件，但需要等待登录后调用Start()才能恢复
        /// </summary>
        public void Start()
        {
            canSend = true;
        }

        /// <summary>
        /// 本组件会第一时间插到TCPClient组件，还没来得及重新登录时调用Pause()暂停，登录后调用Start()恢复
        /// </summary>
        public void Stop()
        {
            canSend = false;
        }

        private void OnSubThreadReceiveMsg(cs_msg_proto msg)
        {
            if (msg.ProtoID == sProtoId)
            {
                //Log($"[{tcp.tag}] 客户端收到心跳反回 id:{sProtoId}");
                timer = SendSuccessInterval;
            }
        }

        public void OnDestroy()
        {
            isRuning = false;
            tcp.onSubThreadReceiveMsg -= OnSubThreadReceiveMsg;
        }

    }
}
